package com.ludomancy.spaceopera.entities;

import java.awt.BasicStroke;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Point;
import java.awt.Stroke;
import java.util.Iterator;
import java.util.Vector;

import com.ludomancy.gamelib.Accumulator;
import com.ludomancy.gamelib.Sound;
import com.ludomancy.gamelib.Utils;
import com.ludomancy.gamelib.entity.EntityRadiusFilter;
import com.ludomancy.spaceopera.BasicEntity;
import com.ludomancy.spaceopera.Game;
import com.ludomancy.spaceopera.InventoryItem;
import com.ludomancy.spaceopera.Player;
import com.ludomancy.spaceopera.SpaceWorld;

public class ScannerItem extends InventoryItem
{
	private Accumulator scanWave = new Accumulator(Game.forTime(2000));
	private int scanMaxRadius = 800;
	private boolean scanning = false;
	
	private Vector twinkleStars = new Vector();
	private Vector twinkleTime = new Vector();
	private Sound scannerSound;
	
	public ScannerItem()
	{
		super(TYPE_SCANNER);
		desc = "Scanner: Your ship can send a distorsion wave to detect special stars.";
		scannerSound = new Sound("telemetry.wav");
		//TODO:fix
		cost = 0;
	}
	
	public void paintPlayerUnderlay(Graphics g, int x, int y)
	{
		// get max arc
		drawWave(g, Game.game.player, scanWave, scanMaxRadius);
		
		for (int i = 0; i < twinkleStars.size(); i++)
		{
			Star star = (Star) twinkleStars.elementAt(i);
			drawWave(g, star, (Accumulator)twinkleTime.elementAt(i), 300);
		}
	}
	
	private void drawWave(Graphics g, BasicEntity entity, Accumulator timer, int maxRadius)
	{
		Graphics2D g2D = (Graphics2D)g;
		Stroke s = g2D.getStroke();
		g2D.setStroke(new BasicStroke(2.0f));
		int arcWidth = (int)Game.game.defaultProjector.worldToScreenX(maxRadius);
		int actualWidth = (int)(timer.getRatio() * arcWidth);
		Utils.pushAlpha(g, 1 - timer.getRatio());
		g.setColor(Color.WHITE);
		Point screenPos = Game.game.defaultProjector.worldToScreen(entity.pos);
		g.drawArc(screenPos.x-actualWidth/2 , screenPos.y-actualWidth/2, actualWidth, actualWidth, 0, 360);
		Utils.popAlpha(g);
		g2D.setStroke(s);
	}
	
	public boolean update()
	{
		for (int i = 0; i < twinkleTime.size(); i++)
		{
			Accumulator star = (Accumulator) twinkleTime.elementAt(i);
			star.update();
			if(star.isDone())
			{
				twinkleTime.removeElementAt(i);
				twinkleStars.removeElementAt(i);
			}
			else
			{
				i++;
			}
		}
		if(scanning)
		{
			scanWave.update();
			
			// get the stars within reach
			int wave = (int)(scanWave.getRatio()*scanMaxRadius);
			Vector stars = Game.game.currentWorld.getEntities(new EntityRadiusFilter(Game.game.player, wave, Star.class));
			for (Iterator iterator = stars.iterator(); iterator.hasNext();)
			{
				Star star = (Star) iterator.next();
				if(star.isSpecial() && !twinkleStars.contains(star))
				{
					twinkleStars.add(star);
					twinkleTime.add(new Accumulator(Game.forTime(1200)));
				}
			}
			if(scanWave.isDone())
			{
				scanWave.reset();
			}
		}
		else
		{
			scanWave.reset();
		}
		return false;
	}

	public void update(Player player, boolean activated)
	{
		if(activated && !scanning && canBeUsed())
		{
			scannerSound.play();
		}
		if(!activated)
		{
			scannerSound.stop();
		}
		scanning = activated;
		
	}

	public boolean canBeUsed()
	{
		return Game.game.currentWorld instanceof SpaceWorld;
	}
}
